package com.qingcheng.service.impl;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.annotation.Service;
import com.github.wxpay.sdk.Config;
import com.github.wxpay.sdk.WXPayRequest;
import com.github.wxpay.sdk.WXPayUtil;
import com.qingcheng.service.order.OrderService;
import com.qingcheng.service.pay.WeixinPayService;
import com.qingcheng.service.seckill.SeckillOrderService;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import tk.mybatis.mapper.common.Mapper;

import java.util.HashMap;
import java.util.Map;

/**
 * Created by yuanxin
 * Date:2019/7/19
 * Time:21:16
 */
@Service
public class WeixinPayServiceImpl implements WeixinPayService {
    @Autowired
    private Config config;
    @Override
    public Map createNative(String orderId, Integer money, String notifyUrl,String... attach) {
        try {
            Map<String, String> map = new HashMap<>();
            map.put("appid",config.getAppID());
            map.put("mch_id",config.getMchID());
            map.put("nonce_str", WXPayUtil.generateNonceStr());
            map.put("body","青橙");
            map.put("out_trade_no",orderId);
            map.put("total_fee",money+"");
            map.put("spbill_create_ip","127.0.0.1");
            map.put("notify_url",notifyUrl);
            map.put("trade_type","NATIVE");
            if (attach != null && attach.length > 0) {
                map.put("attach",attach[0]);
            }

            //xml格式的参数
            String xmlParam = WXPayUtil.generateSignedXml(map, config.getKey());

            WXPayRequest wxPayRequest = new WXPayRequest(config);
            String xmlResult = wxPayRequest.requestWithCert("/pay/unifiedorder", null, xmlParam, false);
            System.out.println("结果: "+xmlResult);

            Map<String, String> mapResult = WXPayUtil.xmlToMap(xmlResult);
            Map<String,String> resultMap = new HashMap<>();
            resultMap.put("code_url",mapResult.get("code_url"));
            resultMap.put("total_fee",money+"");
            resultMap.put("out_trade_no",orderId);
            return resultMap;
        } catch (Exception e) {
            e.printStackTrace();
            return new HashMap();
        }
    }
    @Autowired
    private OrderService orderService;

    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Override
    public void notifyLogic(String xml) {
        try {
            //1.对xml进行解析 map
            Map<String, String> map = WXPayUtil.xmlToMap(xml);
            //2.验证签名
            boolean signatureValid = WXPayUtil.isSignatureValid(map, config.getKey());
            System.out.println("验证签名是否正确: "+signatureValid);
            System.out.println(map.get("out_trade_no"));
            System.out.println(map.get("result_code"));
            System.out.println(map.get("total_fee "));
            if (signatureValid) {
                if (map.get("total_fee").equals(orderService.findById(map.get("out_trade_no")).getPayMoney())) {
                    if ("SUCCESS".equals(map.get("result_code"))) {
                        orderService.updatePayStatus(map.get("out_trade_no"),map.get("transaction_id"));
                        //发送订单号给mq
                        rabbitTemplate.convertAndSend("paynotify","",map.get("out_trade_no"));
                    }else {
                        //记录日志
                    }
                }else {
                    throw new RuntimeException("订单金额不准确");
                }
            }else {
                //记录日志
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public Map queryPaymentResultByOrderId(String orderId) {
        Map<String, String> map = new HashMap<>();
        map.put("appid",config.getAppID());
        map.put("mch_id",config.getMchID());
        map.put("nonce_str", WXPayUtil.generateNonceStr());
        map.put("out_trade_no",orderId);

        try {
            String xmlParam = WXPayUtil.generateSignedXml(map, config.getKey());
            WXPayRequest wxPayRequest = new WXPayRequest(config);
            String xmlResult = wxPayRequest.requestWithCert("/pay/orderquery", null, xmlParam, false);
            Map<String, String> mapResult = WXPayUtil.xmlToMap(xmlResult);
            Map<String, String> resultMap = new HashMap<>();
            resultMap.put("trade_state",mapResult.get("trade_state"));
            resultMap.put("out_trade_no",mapResult.get("out_trade_no"));
            resultMap.put("transaction_id",mapResult.get("transaction_id"));
            return resultMap;
        } catch (Exception e) {
            e.printStackTrace();
            return new HashMap();
        }
    }

    @Override
    public Map closeWXOrderByOrderId(String orderId) {
        Map<String, String> map = new HashMap<>();
        map.put("appid",config.getAppID());
        map.put("mch_id",config.getMchID());
        map.put("nonce_str", WXPayUtil.generateNonceStr());
        map.put("out_trade_no",orderId);

        try {
            String xmlParam = WXPayUtil.generateSignedXml(map, config.getKey());
            WXPayRequest wxPayRequest = new WXPayRequest(config);
            String xmlResult = wxPayRequest.requestWithCert("/pay/closeorder", null, xmlParam, false);
            Map<String, String> mapResult = WXPayUtil.xmlToMap(xmlResult);
            Map<String, String> resultMap = new HashMap<>();
            resultMap.put("out_trade_no",mapResult.get("out_trade_no"));
            resultMap.put("result_code",mapResult.get("result_code"));
            resultMap.put("result_msg",mapResult.get("result_msg"));
            return resultMap;
        } catch (Exception e) {
            e.printStackTrace();
            return new HashMap();
        }
    }


    @Reference
    private SeckillOrderService seckillOrderService;
    /**
     *  System.out.println(map.get("out_trade_no"));
     *  System.out.println(map.get("result_code"));
     *  System.out.println(map.get("total_fee "));
     * @param xml
     * @return
     */
    @Override
    public synchronized String seckillNotifyLogic(String xml) {
        try {
            System.out.println(xml);
            //1.对xml进行解析 map
            Map<String, String> map = WXPayUtil.xmlToMap(xml);
            //2.验证签名
            boolean signatureValid = WXPayUtil.isSignatureValid(map, config.getKey());
            System.out.println("验证签名是否正确: "+signatureValid);
            if (signatureValid) {
                if (map.get("total_fee").equals(seckillOrderService.findById(map.get("attach")).getMoney()/100)){
                    if ("SUCCESS".equals(map.get("result_code"))) {
                        seckillOrderService.updatePayStatus(map.get("out_trade_no"),map.get("transaction_id"),map.get("attach"));
                        //发送订单号给mq
                        rabbitTemplate.convertAndSend("paynotify","",map.get("out_trade_no"));
                    }else {
                        //记录日志
                    }
                }else {
                    throw new RuntimeException("订单金额不准确");
                }
            }else {
                //记录日志
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            //返回封装
            Map<String, String> returnMap = new HashMap<>();
            returnMap.put("return_code","SUCCESS");
            returnMap.put("return_msg","OK");
            String returnXml= null;
            try {
                returnXml = WXPayUtil.mapToXml(returnMap);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return returnXml;
        }
    }
}
